import pin

FETCH = [
    pin.PC_OUT | pin.MAR_IN,
    pin.RAM_OUT | pin.IR_IN | pin.PC_INC,
    pin.PC_OUT | pin.MAR_IN,
    pin.RAM_OUT | pin.DST_IN | pin.PC_INC,
    pin.PC_OUT | pin.MAR_IN,
    pin.RAM_OUT | pin.SRC_IN | pin.PC_INC,
]

MOV = (0 << pin.ADDR2_SHIFT) | pin.ADDR2 # MOV指令定义为 1000 xxxx
ADD = (1 << pin.ADDR2_SHIFT) | pin.ADDR2 # ADD指令定义为 1001 xxxx
SUB = (2 << pin.ADDR2_SHIFT) | pin.ADDR2

INC = (0 << pin.ADDR1_SHIFT) | pin.ADDR1
DEC = (1 << pin.ADDR1_SHIFT) | pin.ADDR1

NOP = 0
HLT = 0x3f

INSTRUCTIONS = {
    2: { # 二地址指令
        MOV: { # MOV指令寻址方式
            (pin.AM_REG, pin.AM_INS): [ # (寄存器寻址，立即寻址) ==> MOV A,5
                pin.DST_W | pin.SRC_OUT, # 微指令：读取SRC寄存器里数据(5)送入DST指定的寄存器(A)中
            ],
            (pin.AM_REG, pin.AM_REG): [ # MOV A, B
                pin.DST_W | pin.SRC_R # 写寄存器（A），读寄存器（B）
            ],
            (pin.AM_REG, pin.AM_DIR): [ # MOV A, [5]
                pin.SRC_OUT | pin.MAR_IN, # 从SRC寄存器读，送到MAR寄存器（RAM地址上）
                pin.DST_W | pin.RAM_OUT # 读取RAM指定地址的数据，写到寄存器（A），
            ],
            (pin.AM_REG, pin.AM_RAM): [ # MOV A, [B]
                pin.SRC_R | pin.MAR_IN, # 读取寄存器（B）数据，送到MAR寄存器（RAM地址上）
                pin.DST_W | pin.RAM_OUT # 读取RAM指定地址的数据，写到寄存器（A）
            ],
            (pin.AM_DIR, pin.AM_INS): [ # MOV [0x2f], 5
                pin.DST_OUT | pin.MAR_IN, # 读取DST寄存器数据，送到MAR寄存器（RAM地址上）
                pin.RAM_IN | pin.SRC_OUT # 从SRC寄存器读取数据5，写入RAM中
            ],
            (pin.AM_DIR, pin.AM_REG): [ # MOV [0x2f], A
                pin.DST_OUT | pin.MAR_IN,
                pin.RAM_IN | pin.SRC_R
            ],
            (pin.AM_DIR, pin.AM_DIR): [ # MOV [0x2f], [0x2e]
                pin.SRC_OUT | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_OUT | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
            (pin.AM_DIR, pin.AM_RAM): [ # MOV [0x2f], [A]
                pin.SRC_R | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_OUT | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
            
            (pin.AM_RAM, pin.AM_INS): [ # MOV [A], 5
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.SRC_OUT
            ],
            (pin.AM_RAM, pin.AM_REG): [ # MOV [A], B
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.SRC_R
            ],
            (pin.AM_RAM, pin.AM_DIR): [ # MOV [A], [0x30]
                pin.SRC_OUT | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
            (pin.AM_RAM, pin.AM_RAM): [ # MOV [A], [B]
                pin.SRC_R | pin.MAR_IN,
                pin.RAM_OUT | pin.T1_IN,
                pin.DST_R | pin.MAR_IN,
                pin.RAM_IN | pin.T1_OUT
            ],
        },
        ADD: {
            (pin.AM_REG, pin.AM_INS): [ # ADD D, 5
                pin.DST_R | pin.A_IN,
                pin.SRC_OUT | pin.B_IN,
                pin.OP_ADD | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
            (pin.AM_REG, pin.AM_REG): [ # ADD D, C
                pin.DST_R | pin.A_IN,
                pin.SRC_R | pin.B_IN,
                pin.OP_ADD | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
        SUB: {
            (pin.AM_REG, pin.AM_INS): [ # SUB D, 5
                pin.DST_R | pin.A_IN,
                pin.SRC_OUT | pin.B_IN,
                pin.OP_SUB | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
            (pin.AM_REG, pin.AM_REG): [ # SUB D, C
                pin.DST_R | pin.A_IN,
                pin.SRC_R | pin.B_IN,
                pin.OP_SUB | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
    },
    1: {
        INC: {
            pin.AM_REG: [
                pin.DST_R | pin.A_IN,
                pin.OP_INC | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
        DEC: {
            pin.AM_REG: [
                pin.DST_R | pin.A_IN,
                pin.OP_DEC | pin.ALU_OUT | pin.DST_W | pin.ALU_PSW
            ],
        },
    }, # 一地址指令
    0: { # 零地址指令
        NOP: [
            pin.CYC, # 让指令周期清零，跳过这次指令
        ],
        HLT: [
            pin.HLT, # 指令停止
        ]
    }
}

# print(bin(MOV))